package Environment;

/**
 * Creates an environment which consists of moving entities. 
 * It oversees the moving entities which are part of it,
 * contains a boundary and a Canvas. It acts as a Controller
 * for the moving entities. 
 * 
 * @author Ga-Young Joung and Perry Zheng
 */

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;

import individual.*;
import utilities.Vector;
import view.Canvas;

public class Environment {
	private List<MovingEntity> myIndividuals;
    private List<MovingEntity> myIndividualsToRemove;
	private Canvas myView;
	private Boundary myBoundary;
	
	/**
	 * Creates an Environment from a Canvas. 
	 * @param view
	 */
	public Environment(Canvas view) {
		myView = view;
		myBoundary = new InfiniteBoundary(this);
        myIndividuals = new ArrayList<MovingEntity>();
        myIndividualsToRemove = new ArrayList<MovingEntity>();
	}
	
	/**
	 * Creates an Environment from a specified Canvas and a boundary.
	 * @param view
	 * @param boundary
	 */
	public Environment(Canvas view, Boundary boundary) {
		myView = view;
		myBoundary = boundary;
        myIndividuals = new ArrayList<MovingEntity>();
        myIndividualsToRemove = new ArrayList<MovingEntity>();
	}
	
	/**
	 * Update the moving entities inside the environment
	 */
	public void update() {
        myIndividualsToRemove.clear();
		for (MovingEntity current : myIndividuals) {
        	if (current.isDead()) {
        		myIndividualsToRemove.add(current);
        	} else {
        		current.update(myIndividuals);
        	}
		}
        for (MovingEntity current : myIndividualsToRemove)
        {
            myIndividuals.remove(current);
        }
	}
	
    /**
     * Remember given mover so it is painted on Canvas.
     * 
     * Note, movers are rendered in the order they are added.
     * 
     * @param m mover to be added to those that are drawn
     */
    public void add (MovingEntity shape) 
    {
    	myIndividuals.add(shape);
    }
    
    /**
     * Remove given individual so it is not painted on Canvas.
     * 
     * @param m mover to be added to those that are drawn
     */
    public void remove (MovingEntity shape)
    {
        myIndividualsToRemove.add(shape);
    }
    
    /**
     * Remove all Individuals from the canvas.
     */
    public void clear ()
    {
        myIndividuals.clear(); 
    }
    
    /**
     * Gets all the moving entities in the environment
     * @return All the moving entities in the environment
     */
    public List<MovingEntity> getIndividuals() {
    	return myIndividuals;
    }
    
    /**
     * Sets the boundary for the environment
     * @param boundary - the specified boundary that the Environment wants to have
     */
	public void setBoundary(Boundary boundary) {
		myBoundary = boundary;
	}
	
	public Boundary getBoundary() {
		return myBoundary;
	}
	
	/**
	 * Return the new position and velocity when a moving entity
	 * hits on the boundary. 
	 * @param center - the current center of the moving entity
	 * @param velocity - the current velocity of the moving entity
	 * @param sizeOfEntity - the size (i.e. radius) of the moving entity
	 * @return - the new position and new velocity of the moving entity
	 */
	public ArrayList<Vector> getNewPositionAndVelocity(Vector center, Vector velocity, Dimension sizeOfEntity) {
		return myBoundary.getNewPositionAndVelocity(center, velocity, sizeOfEntity);
	}
	
	/**
	 * Returns the dimension of the Canvas
	 * @return - the size of the Canvas 
	 */
	public Dimension getSize() {
		return myView.getSize();
	}
	
}
